using System;
using System.Collections.Specialized;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Configuration;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
using System.Data.SqlClient;
using Common;

public partial class tm_TreeViewAdv : System.Web.UI.UserControl
{
    private fAfterPageLoad privAfterPageLoad = null;
    public delegate void fAfterPageLoad();
    public bool LoadDataOnPageLoad = true;   
    
    //Public method
    #region public
    public fAfterPageLoad AfterPageLoad
    {
        get { return privAfterPageLoad; }
        set { privAfterPageLoad = value; }
    }

    public string dataTableName //Table to get data
    {
        set { lblDataTableName.Text = value; }
        get { return lblDataTableName.Text; }
    }
    public string valueFldName  //Data field used as node's value 
    {
        set { lblValueFldName.Text = value; }
        get { return lblValueFldName.Text; }
    }
    public string textFldName //Data field used as node's display text
    {
        set { lblTextFldName.Text = value; }
        get { return lblTextFldName.Text; }
    }
    public string parentFldName //Data field used as parent node's value 
    {
        set { lblParentCodeFldName.Text = value; }
        get { return lblParentCodeFldName.Text; }
    }
    public bool searchVisible
    {
        set {pnlSearch.Visible = value;}
        get { return pnlSearch.Visible; }
    }
    public int maxDepth  //Maximum depth to display: -1 = all sub-nodes 
    {
        set { lblMaxDepth.Text = value.ToString(); }
        get
        {
            int depth = -1; int.TryParse(lblMaxDepth.Text, out depth);
            return depth;
        }
    }
    public int myMaxWordNoPerRow
    {
        set { lblMaxWordPerRow.Text = value.ToString(); }
        get {
            int tmp = 0;int.TryParse(lblMaxWordPerRow.Text.ToString(), out tmp);
            return tmp; ; 
        }
    }

    public int myHeight
    {
        set { pnlTreeView.Height = (int)value; }
        get { return (int)pnlTreeView.Height.Value; }
    }

    public int myWidth
    {
        set
        {
            pnlTreeView.Width = (int)value;
            txtSearch.Width = value - (int)btnSearch.Width.Value;
        }
        get { return (int)pnlTreeView.Width.Value; }
    }
 
    public TreeView myTreeView
    {
        get { return this.TreeViewObj; }
    }
    
    public void SetSelectedNodes(ArrayList seletedNodes)
    {
        for (int idx = 0; idx < seletedNodes.Count; idx++)
        {
            SelectNodes(seletedNodes[idx].ToString().Trim(), myTreeView.Nodes);
        }
    }

    private void SelectNodes(string nodeValue,TreeNodeCollection tnCollection)
    {
        if (tnCollection == null) return;
        //Find the most suitable parents's node
        for (int idx = 0; idx < tnCollection.Count; idx++)
        {
            if (nodeValue == tnCollection[idx].Value.Trim())
            {
                tnCollection[idx].Checked = true;
                return;
            }
            // The most suitable parents's node was found ?
            // Oh Yes, load all child nodes and stop
            if (nodeValue.StartsWith(tnCollection[idx].Value.Trim()))
            {
                //The parents's was loaded ? If not, load its child nodes
                if (tnCollection[idx].ChildNodes.Count == 0)
                {
                    PopulateSubLevel(tnCollection[idx].Value, tnCollection[idx]);
                    //Turn-off PopulateOnDemand to prevent reload in TreeNodePopulate event
                    tnCollection[idx].PopulateOnDemand = false;
                }
                tnCollection[idx].Expand(); 
                //Repeate the task from the child node 
                if (tnCollection[idx].ChildNodes.Count != 0)
                    SelectNodes(nodeValue, tnCollection[idx].ChildNodes);
                break;
            }
        }
    }

    public ArrayList GetSelectedNodes()
    {
        ArrayList seletedNodes = new ArrayList();
        if (myTreeView.CheckedNodes.Count == 0) return seletedNodes;
        foreach (TreeNode tn in myTreeView.CheckedNodes)
        {
            seletedNodes.Add(tn.Value.Trim());
        }
        return
            seletedNodes;
    }
    public Hashtable GetSelectedNodesHashtable()
    {
        Hashtable seletedNodes = new Hashtable();
        if (myTreeView.CheckedNodes.Count == 0) return seletedNodes;
        foreach (TreeNode tn in myTreeView.CheckedNodes)
        {
            seletedNodes.Add(tn.Text.Trim(), tn.Value.Trim());
        }
        return seletedNodes;
    }

    #endregion

    #region Event handler
    protected void Page_Load(object sender, EventArgs e)
    {
        if (dataTableName.Trim() == "" || valueFldName.Trim() == "" || 
            textFldName.Trim()=="" || parentFldName.Trim()=="") 
        {
            Common.sysLibs.ShowErrorNotice(lblNotice,"Chua khoi tao cac gia tri yeu cau"); 
            //throw new ArgumentException("Chua khoi tao ham [DataQueryCmd]");
            return;
        }
        //Keep search visible state.
        searchVisible = searchVisible;
        if (!Page.IsPostBack)
        {
            lblNotice.Visible = false;
            //selectedNodes = null;
            //javascript on check all
            myTreeView.Attributes.Add("onclick", "OnTreeClick(event)");
            //show tree on page load
            if (LoadDataOnPageLoad && !LoadData()) return;
        }
    }
    protected void TreeViewObj_TreeNodePopulate(object sender, TreeNodeEventArgs e)
    {
        //Do not show the out-of-favoured nodes
        if ((maxDepth > 0) && e.Node.Depth >= maxDepth) return;
        if (!PopulateSubLevel(e.Node.Value, e.Node)) return;
    }
    protected void btnSearch_Click(object sender, EventArgs e)
    {
        PopulateRootLevel();
    }
    #endregion

    public bool LoadData()
    {
        if (!PopulateRootLevel()) return false;
        if (privAfterPageLoad != null)  privAfterPageLoad();
        return true;
    }
    protected void PopulateNodes(DataTable dt, TreeNodeCollection nodes)
    {
        int maxWordPerRow = 0; int.TryParse(lblMaxWordPerRow.Text, out maxWordPerRow); 
        foreach (DataRow dr in dt.Rows)
        {
            TreeNode tn = new TreeNode();
            if (maxWordPerRow>0)
                tn.Text = Common.sysLibs.SplitToMultiLine(dr[textFldName].ToString().Trim(), maxWordPerRow);
            else tn.Text = dr[textFldName].ToString().Trim();
            tn.Value = dr[valueFldName].ToString().Trim();
            tn.SelectAction = TreeNodeSelectAction.None;
            nodes.Add(tn);

            //If node has child nodes, then enable on-demand populating
            tn.PopulateOnDemand = ((int)(dr["childnodecount"]) > 0);
        }
    }
    protected bool PopulateRootLevel()
    {
        try
        {
            string SQLCmd = BuildQueryCommand(dataTableName, valueFldName, textFldName, parentFldName + " IS NULL");
            SqlConnection objConn = new SqlConnection(sysLibs.GetConnectionString);
            SqlCommand objCommand = new SqlCommand(SQLCmd, objConn);
            SqlDataAdapter da = new SqlDataAdapter(objCommand);
            DataTable dt = new DataTable();
            da.Fill(dt);
            myTreeView.Nodes.Clear(); 
            PopulateNodes(dt, myTreeView.Nodes);
            //To prevent the load  of all sub-nodes
            myTreeView.CollapseAll(); 
        }
        catch (Exception er) 
        {
            Common.sysLibs.ShowErrorNotice(lblNotice,er.Message.ToString());
            return false;
        }
        return true;
    }

    protected bool PopulateSubLevel(string parentCode, TreeNode parentNode)
    {
        string SQLCmd = BuildQueryCommand(dataTableName, valueFldName, textFldName, parentFldName+ "='" + parentCode+"'");
        try
        {
            SqlConnection objConn = new SqlConnection(sysLibs.GetConnectionString);
            SqlCommand objCommand = new SqlCommand(SQLCmd, objConn);
            SqlDataAdapter da = new SqlDataAdapter(objCommand);
            DataTable dt = new DataTable();
            da.Fill(dt);
            PopulateNodes(dt, parentNode.ChildNodes);
            //sysLibs.ShowErrorNotice(lblNotice, SQLCmd);
        }
        catch (Exception er)
        {
            Common.sysLibs.ShowErrorNotice(lblNotice, er.Message.ToString());
            return false;
        }
        return true;
    }

    private string BuildQueryCommand(string tableName, string valueFldName, string textFldName, string filterCond)
    {
        string SQLCmd= 
            "SELECT " + valueFldName + "," + textFldName +
                ",(SELECT COUNT(*) FROM " + tableName +
                " WHERE " + parentFldName + "=deprived." + valueFldName +
                ") childnodecount " +
            "FROM " + tableName + " deprived ";

        //Automatically add filter to ensure that expected nodes ared displayed
        if (pnlSearch.Visible && txtSearch.Text.Trim() != "")
        {
            filterCond = (filterCond.Trim() != "" ? "" : " AND ") +
                        " (" + textFldName + " LIKE N'" + Common.consts.constSQLAllWildcard +
                        txtSearch.Text.Trim() + Common.consts.constSQLAllWildcard + "')";
        }
        if (filterCond.Trim()!= "")
            SQLCmd += "WHERE  " + filterCond;
        return SQLCmd;
    }
}
